package com.example.CarManagement.handler;

import com.example.CarManagement.sys.entity.LoginUser;
import com.example.CarManagement.sys.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

public class MyWebSocketHandler extends TextWebSocketHandler {

    @Resource
    private IUserService userService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /* ① 用来快速找 session */
    private static final Map<String, WebSocketSession> SESSION_MAP = new ConcurrentHashMap<>();


    private static final Set<WebSocketSession> sessions = ConcurrentHashMap.newKeySet();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        sessions.add(session);
        String token = extractToken(session);


        System.out.println(session.getUri());
        if (token == null) {
            try {
                session.close(CloseStatus.NOT_ACCEPTABLE);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return;
        }

        LoginUser userDetails = validateToken(token);// ① 取 token
        if (userDetails == null) {                   // ② 验签
            try {
                session.close(CloseStatus.NOT_ACCEPTABLE); // ③ 直接断
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return;
        }
        // 储存SessionId SESSION_MAP
        SESSION_MAP.put(session.getId(), session); // 新增

        redisTemplate.opsForValue().set(userDetails.getUserId(), session.getId());
    }

    /* 验证用户 */
    private LoginUser validateToken(String token) {
        try {
            return userService.getUserInfo(token);
        } catch (Exception e) {
            return null;
        }
    }

    /* 从 URL 里摘 authorization */
    private String extractToken(WebSocketSession session) {
        String query = Objects.requireNonNull(session.getUri()).getQuery();
        if (query == null) return null;
        return Arrays.stream(query.split("&")).filter(kv -> kv.startsWith("authorization=")).map(kv -> kv.substring(14)).findFirst().orElse(null);
    }

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        // 收到消息可立即回推
        String payload = message.getPayload();
        broadcast("echo -> " + payload);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        sessions.remove(session);
        System.out.println("客户端断开");
    }

    /* ④ 供外部调用的精准推送 */
    public boolean sendToSession(String sessionId, String msg) {
        WebSocketSession s = SESSION_MAP.get(sessionId);
        if (s != null && s.isOpen()) {
            try {
                s.sendMessage(new TextMessage(msg));
                return true;
            } catch (IOException e) {
                // 发送失败，可把 session 移除
                return false;
            }
        }
        return false;
    }

    /* 服务端主动推送 */
    public void broadcast(String msg) {
        TextMessage tm = new TextMessage(msg);
        sessions.forEach(s -> {
            try {
                s.sendMessage(tm);
            } catch (IOException ignore) {
            }
        });
    }
}